package cn.kow.kmall.controller.system;

import cn.kow.kmall.controller.BaseController;
import cn.kow.kmall.core.exception.ServiceException;
import cn.kow.kmall.core.response.KmallResult;
import cn.kow.kmall.core.util.Base64;
import cn.kow.kmall.core.util.JwtTokenUtils;
import cn.kow.kmall.core.util.UUIDUtils;
import cn.kow.kmall.core.util.VerifyCodeUtils;
import cn.kow.kmall.system.entity.SysUser;
import cn.kow.kmall.admin.pojo.dto.LoginDTO;
import cn.kow.kmall.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author: lijun
 * @Description:
 * @Date: Created in 2019-10-29 17:04
 * @Modified By:
 */
@Slf4j
@RestController
public class LoginController extends BaseController {

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private SysUserService sysUserService;

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expire}")
    private Long expire;

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/login/code")
    public KmallResult loginCode() {
        // 生成随机字串
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        // 唯一标识
        String uuid = UUIDUtils.get32UUID();

        // 生成图片
        int w = 111, h = 36;
        // 保存到Redis
        redisTemplate.opsForValue().set("login:code:" + uuid, verifyCode, 60, TimeUnit.SECONDS);
        try(ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
            VerifyCodeUtils.outputImage(w, h, stream, verifyCode);
            return KmallResult.success()
                    .put("uuid", uuid)
                    .put("img", Base64.encode(stream.toByteArray()));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return KmallResult.fail(e.getMessage());
        }
    }

    @PostMapping("/login")
    public KmallResult login(@RequestBody LoginDTO loginDTO) {
        // 验证码校验
        String codeKey = "login:code:" + loginDTO.getUuid();
        if (redisTemplate.hasKey(codeKey)) {
            String cacheCode = (String) redisTemplate.opsForValue().get(codeKey);
            if (!cacheCode.equals(loginDTO.getCode())) {
                return KmallResult.fail("登录失败，验证码错误");
            }
        } else {
            return KmallResult.fail("登录失败，验证码已失效");
        }

        String username = loginDTO.getUsername();
        try {
            SysUser sysUser = sysUserService.findByUserName(loginDTO.getUsername());
            if (!passwordEncoder.matches(loginDTO.getPassword(), sysUser.getPassword())) {
                return KmallResult.fail("登录失败，用户名密码错误");
            }
        } catch (ServiceException e) {
            return KmallResult.fail(e.getMessage());
        } catch (Exception e){
            e.printStackTrace();
            return KmallResult.fail("登录失败，系统繁忙");
        }
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", username);
        String token = JwtTokenUtils.generateToken(username, claims, secret, expire);
        return KmallResult.success().put("token", token);
    }

    @PostMapping("/logout")
    public KmallResult logout() {
        return KmallResult.success();
    }

}

